unit sci.equation;

interface
uses
  SysUtils, sci.term, sci.log, sci.simplifier;

type
  TEquation = class
  private
    left, right: TTermList; (* Left and right side *)
  public
    constructor Create(expr: string);
    procedure MoveTerms;
    function Solve: string;
  end;

implementation

constructor TEquation.Create(expr: string);
var
  posi: integer;
begin
  posi := pos('=', expr);
  if posi = 0 then raise Exception.Create('''='' not found.');
  left := TTermList.Create(copy(expr, 1, posi - 1));
  right := TTermList.Create(copy(expr, posi + 1, length(expr) - posi));
end;

(*******************************************************************************
 *                       TEquation.MoveTerm
 *******************************************************************************)
(*  Move all the terms that contain unknown to the left side and others to the
 *  right side.
 *
 *******************************************************************************)
procedure TEquation.MoveTerms;
var
  i: integer;
begin
  for i := 1 to left.cnt do
  begin
    if not left.terms[i].ContainsUnk then
    begin
      left.terms[i].coefficient := -left.terms[i].coefficient;
      right.Insert(left.terms[i]);
      left.Remove(left.terms[i]);
    end;
  end;

  for i := 1 to right.cnt do
  begin
    if right.terms[i].ContainsUnk then
    begin
      right.terms[i].coefficient := -right.terms[i].coefficient;
      left.Insert(right.terms[i]);
      right.Remove(right.terms[i]);
    end;
  end;
end;

function TEquation.Solve: string;
var
  ucnt, hexp: integer;
begin
  MoveTerms;
  left := TSimplifier.Simplify(left);
  right := TSimplifier.Simplify(right);
  left.Print;
  ucnt := left.CountUnk;
  hexp := left.HighestExp;

  dbgprint(IntToStr(ucnt) + IntToStr(hexp));
  if (ucnt = 1) and (hexp = 1) then
  begin
    Result := left.terms[1].unk[1].unk + ' = ' + FloatToStr(right.terms[1].coefficient /
                                                left.terms[1].coefficient);
  end;
end;

end.
